package com.zy.design.demo.creational;

/**
 * 原型模式
 * 特点：通过克隆创建对象。
 */
class Prototype implements Cloneable {
    private String data;

    public Prototype(String data) { this.data = data; }

    @Override
    public Prototype clone() throws CloneNotSupportedException {
        return (Prototype) super.clone();
    }

    public void setData(String data) {
        this.data = data;
    }

    public void display() { System.out.println("数据: " + data); }
}
class PrototypeDemoObject implements Cloneable {
    private Funny data;

    public PrototypeDemoObject(Funny data) { this.data = data; }

    @Override
    public PrototypeDemoObject clone() throws CloneNotSupportedException {
        return (PrototypeDemoObject) super.clone();
    }

    public void setData(Funny data) {
        this.data = data;
    }

    public Funny getData() {
        return data;
    }

    public void display() { System.out.println("数据: " + data.getName()); }
}

class Funny{
    private String name;

    public Funny(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class Main3 {
    public static void main(String[] args) throws CloneNotSupportedException {

        System.out.println("==========先试试非对象.看看原型模式====================================");
        Prototype p1 = new Prototype("原始数据");
        p1.display();
        Prototype p2 = p1.clone();
        p2.display();

        System.out.println("对象是否是同一对象"+p1.equals(p2));
        p2.setData("改了p2的数据");
        p1.display();
        p2.display();
        System.out.println(p1.hashCode());
        System.out.println(p2.hashCode());
        System.out.println("==========试试对象====================================");
        PrototypeDemoObject pObject1 = new PrototypeDemoObject(new Funny("原始数据"));
        pObject1.display();
        PrototypeDemoObject pObject2 = pObject1.clone();
        pObject2.display();
        System.out.println("============开始修改===================");
        pObject1.getData().setName("改下1");
        pObject2.getData().setName("改下2");
        System.out.println("============修改后display===================");
        pObject1.display();//数据: 改下2
        pObject2.display();//数据: 改下2
        System.out.println("============set后===================");
        System.out.println("源对象"+pObject1.hashCode());
        System.out.println("克隆后"+pObject2.hashCode());
        System.out.println("源对象中对象"+pObject1.getData().hashCode());
        System.out.println("克隆后中对象"+pObject2.getData().hashCode());
        System.out.println("源对象中对象中属性"+pObject2.getData().getName().hashCode());
        System.out.println("克隆后中对象中属性"+pObject2.getData().getName().hashCode());
    }
}
